The
next folder you see under Databases in the Object Explorer is Database
Snapshots. Database snapshots were introduced in SQL Server 2005 and
provide you with the ability to create a read-only copy of a database at
a given point in time. Any transactions that are uncommitted at the
time you create a snapshot will not be included in the database
snapshot. You can create multiple snapshots of a source database, but
those snapshots must reside on the same instance as the source database.
A database snapshot only
contains the data pages that have changed in the source database since
the snapshot was created. It contains the original copies of those pages
in order to give the effect of a read-only view. The file that is
created to hold the changed data pages when the snapshot is created is
known as a sparse file. A database snapshot sparse file will start out very small and will grow larger as changes are made to the source database.
A database snapshot can never
be any bigger than the size of the source database at the time the
snapshot was created. Since the snapshot only contains changed pages, it
relies on the source database to provide the pages that have not
changed; if the source database is unavailable, then so is the snapshot.
A source database that contains a snapshot cannot be dropped, detached,
or restored until all of the snapshots have been dropped.
You can use database
snapshots for things such as reporting solutions and reverting the
source database back to the time the snapshot was taken. Using a
snapshot as a reporting solution is very helpful when using database
mirroring.
You can create a database snapshot on all the database recovery models,
but database snapshots are only available in the Enterprise Edition of
SQL Server.
1. Creating a Database Snapshot
To create a database snapshot, you must issue the CREATE DATABASE command with the AS SNAPSHOT OF
clause; you cannot create a database snapshot using the SQL Server
Management Studio GUI. Any user who has the right to create a database
can create a database snapshot.
Before you create a
database snapshot, you need to know the logical files names for every
data file in the source database. You can get the logical file name by
executing the following query against the source database:
SELECT name FROM sys.database_files WHERE type <> 1
Listing 9-1 shows the syntax for creating a new database snapshot against the AdventureWorks database. Following are the parameters used in that script:
Test_Snapshot_1 is the name of the new database snapshot.
AdventureWorks_Data is the logical file name of the data file in the AdventureWorks database.
FileName
is the name of the snapshot file that will hold the changed data files.
You can use any file name, extension, and location that you like for
the snapshot file.
AdventureWorks is the source database name following the AS SNAPSHOT OF clause.
Example 1. Syntax Used to Generate a Database Snapshot
CREATE DATABASE Test_Snapshot_1 ON (Name = AdventureWorks_Data, FileName = 'C:\Test_Data.ss') AS SNAPSHOT OF AdventureWorks
|
To create a database snapshot with multiple filegroups, you need to supply the Name and FileName parameters for each filegroup, as shown in Listing 2.
Example 2. Syntax Used to Generate a Database Snapshot Using Multiple Filegroups
CREATE DATABASE <Snapshot Name> ON (Name = <Logical_FileName_1>, FileName =<Snapshot File Location 1>), (Name =<Logical_FileName_2>, FileName =<Snapshot File Location 2>) AS SNAPSHOT OF <DatabaseName>
|
2. Viewing and Querying a Snapshot
Once you have created a
snapshot, you can view it in the Database Snapshots folder under the
Databases node in the SQL Server Management Studio Object Explorer .
You can now query the snapshot as if it were any other database. Notice that if you query sys.database_files as shown in Figure 1, the physical file names are actually the source database file names and not the snapshot file names created back in Listing 1. Querying the snapshot gives the effect of querying an exact copy of the source database at the time you created the snapshot.
Since querying the snapshot returns metadata about the source database, you have to query the master database (as shown in Listing 3) to return the metadata for the snapshot.
Example 3. Query to View the Snapshot Metadata
SELECT B.name DatabaseName, A.name LogicalName, B.database_id, B.source_database_id, A.physical_name FROM master.sys.master_files A JOIN master.sys.databases B ON A.database_id = B.database_id
|
You can see the result set of Listing 9-3 in Figure 2. Notice that the snapshot database name Test_Snapshot_1 has a value of 6 for the source_database_id, which references the database_id of the AdventureWorks database.
To drop a snapshot, all you need to do is issue the DROP DATABASE command using the same syntax you would use to drop any database. Run the following statement to drop the Test_Snapshot_1 database snapshot used in this section:
DROP DATABASE Test_Snapshot_1
3. Reverting a Database to a Database Snapshot
You can revert a source database to the state it was in at the time a snapshot was taken using the RESTORE DATABASE statement with the FROM DATABASE_SNAPSHOT
clause. Reverting a database is a quick way to roll back major changes
to the source database. For example, you may want to create a database
snapshot prior to running vendor-supplied upgrade scripts. Reverting a
database due to an error will often be faster than restoring the entire
database because only the changed pages will have to be overwritten.
Reverting a database does not, however, replace the need for a good
database backup. If the source database becomes corrupt, you will not be
able to revert it using a snapshot.
When a source database is
restored using a snapshot, the updated data files on the source database
are overwritten using the data pages from the snapshot sparse file. The
log file in the source database is then overwritten and re-created.
Before you revert a database to a snapshot, you should do the following:
Make sure the source database does not contain read-only or compressed filegroups.
Make sure all the files are online that were online when the snapshot was created.
Delete all snapshots of the source database, except the one you are reverting to.
Once you decide to revert a
source database to a snapshot, you will need the source database name
and the name of the snapshot. You can get the database names by running
the query that was shown in Listing 3.
While you are gathering the database names, you should also verify that
the snapshot you are reverting to is the only snapshot with the source_database_id of the database you will be reverting. Then use the syntax shown in Listing 4 to revert your database. The listing reverts the AdventureWorks database to a snapshot named Test_Snapshot_1. If you have already dropped the snapshot we created in the previous section, you can re-create it by running the code in Listing 1.
Example 4. Syntax Used to Revert a Database to a Database Snapshot
USE master GO RESTORE DATABASE AdventureWorks FROM DATABASE_SNAPSHOT = 'Test_Snapshot_1'
|
NOTE
Reverting a database breaks
the log backup chain, so you need take a full backup of a database once
it has been reverted. If you do not take a full backup of the database
before you try to take a transaction log backup, you will receive an
error message stating that the BACKUP LOG cannot be performed because there is no current database backup.